﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using Fayshine.VA.Models;
using Fayshine.VA.RIAService.Web;
using Fayshine.VA.ViewModels;
using Visifire.Charts;
using LocalBusyIndicator = Fayshine.VA.Controls.BusyIndicator;

namespace Fayshine.VA.Views
{
    public partial class RealTimeCurve : Page
    {
        private PassengerFlowViewModel m_ViewModel;
        public RealTimeCurve()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(RealTimeCurve_Loaded);
        }

        private void RealTimeCurve_Loaded(object sender, RoutedEventArgs e)
        {
            LocalBusyIndicator indicator = Application.Current.RootVisual as LocalBusyIndicator;
            indicator.IsBusy = true;

            m_ViewModel = new PassengerFlowViewModel();
            m_ViewModel.ResetRealTimeEventHandler += new ResetRealTimeChartEventHandler(m_ViewModel_ResetRealTimeEventHandler);
            m_ViewModel.AppendGatePassengerFlow += new AppendGatePassengerFlowEventHandler(m_ViewModel_AppendGatePassengerFlow);
            this.DataContext = m_ViewModel;

            m_ViewModel.GetAllAreas();
        }

        private void m_ViewModel_AppendGatePassengerFlow(string name, bool isIn, List<GatePassengerFlow> gatePassengerFlows)
        {
            this.Dispatcher.BeginInvoke(delegate()
             {
                 DataSeries series = new DataSeries();
                 series.RenderAs = RenderAs.Spline;
                 series.LegendText = name;
                 series.XValueType = ChartValueTypes.Time;
                 series.XValueFormatString = "HH:mm";
                 series.LineThickness = Helpers.FayshineManager.DiagramLineThickness;
                 series.MarkerSize = 0;

                 DataMapping mappingXItem = new DataMapping();
                 mappingXItem.MemberName = "XValue";
                 mappingXItem.Path = "DisplayTime";
                 series.DataMappings.Add(mappingXItem);

                 DataMapping mappingYItem = new DataMapping();
                 mappingYItem.MemberName = "YValue";
                 if (isIn)
                 {
                     mappingYItem.Path = "InCount";
                 }
                 else
                 {
                     mappingYItem.Path = "OutCount";
                 }
                 series.DataMappings.Add(mappingYItem);

                 series.DataSource = gatePassengerFlows;

                 vcChart.Series.Add(series);

                 if (isIn)
                 {
                     dataGrid.Columns[0].Visibility = System.Windows.Visibility.Visible;
                     dataGrid.Columns[1].Visibility = System.Windows.Visibility.Visible;
                     dataGrid.Columns[2].Visibility = System.Windows.Visibility.Visible;
                     dataGrid.Columns[3].Visibility = System.Windows.Visibility.Visible;
                     dataGrid.Columns[4].Visibility = System.Windows.Visibility.Collapsed;
                     dataGrid.Columns[5].Visibility = System.Windows.Visibility.Collapsed;
                     dataGrid.Columns[6].Visibility = System.Windows.Visibility.Collapsed;
                     dataGrid.Columns[7].Visibility = System.Windows.Visibility.Collapsed;
                     dataGrid.Columns[8].Visibility = System.Windows.Visibility.Collapsed;
                 }
                 else
                 {
                     dataGrid.Columns[0].Visibility = System.Windows.Visibility.Visible;
                     dataGrid.Columns[1].Visibility = System.Windows.Visibility.Collapsed;
                     dataGrid.Columns[2].Visibility = System.Windows.Visibility.Collapsed;
                     dataGrid.Columns[3].Visibility = System.Windows.Visibility.Collapsed;
                     dataGrid.Columns[4].Visibility = System.Windows.Visibility.Visible;
                     dataGrid.Columns[5].Visibility = System.Windows.Visibility.Visible;
                     dataGrid.Columns[6].Visibility = System.Windows.Visibility.Visible;
                     dataGrid.Columns[7].Visibility = System.Windows.Visibility.Collapsed;
                     dataGrid.Columns[8].Visibility = System.Windows.Visibility.Collapsed;
                 }

             });

        }

        private void m_ViewModel_ResetRealTimeEventHandler()
        {
            this.Dispatcher.BeginInvoke(delegate()
             {
                 if (vcChart != null)
                 {
                     vcChart.Series.Clear();
                 }
             });
        }

        // Executes when the user navigates to this page.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {

        }

        private void cmbAreas_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (m_ViewModel != null)
            {
                LocalBusyIndicator indicator = Application.Current.RootVisual as LocalBusyIndicator;
                indicator.IsBusy = true;

                //m_ViewModel.GetRealTimePassengerFlow((int)cmbAreas.SelectedValue);
            }
        }

        private void cmbAreas_DropDownOpened(object sender, EventArgs e)
        {
            
        }

        private void cmbAreas_DropDownClosed(object sender, EventArgs e)
        {
            if (m_ViewModel != null)
            {
                List<area> selectedArea = new List<area>();
                var selectAreaExt = m_ViewModel.AreaExtends.Where(a => a.IsSelected).ToList();
                selectAreaExt.ForEach(b => {
                    area temp = b.Tag as area;
                    selectedArea.Add(temp);
                });

                if (selectedArea.Count > 0)
                {
                    cbItemDisplay.Content = selectedArea.Count > 1 ? selectedArea[0].Name + "..." : selectedArea[0].Name;

                    if (selectedArea.Count > 1)
                    {
                        this.cmbPassenger.IsEnabled = false;
                    }
                    else
                    {
                        this.cmbPassenger.IsEnabled = true;
                    }

                }
                else
                {
                    cbItemDisplay.Content = string.Empty;
                }
                cmbAreas.SelectedItem = null;
                cmbAreas.SelectedItem = cbItemDisplay;
                
                m_ViewModel.SelectAreasChanged(selectedArea,false);
            }
        }

        private void cmbPassenger_DropDownOpened(object sender, EventArgs e)
        {
        }

        private void cmbPassenger_DropDownClosed(object sender, EventArgs e)
        {
            if (m_ViewModel != null)
            {
                var selectMonitorAreaExts = m_ViewModel.MonitorAreaGateExts.Where(a => a.IsSelected).ToList();

                if (selectMonitorAreaExts.Count > 0)
                {
                    cbItemDisplay2.Content = selectMonitorAreaExts.Count > 1 ? selectMonitorAreaExts[0].Name + "..." : selectMonitorAreaExts[0].Name;

                }
                else
                {
                    cbItemDisplay2.Content = string.Empty;
                }
                cmbPassenger.SelectedItem = null;
                cmbPassenger.SelectedItem = cbItemDisplay2;
            }
        }

        private void btnMonitor_Click(object sender, RoutedEventArgs e)
        {
            bool isAreaGateSelected = true;
            var selectAreaExt = m_ViewModel.AreaExtends.Where(a => a.IsSelected).ToList();
            if (selectAreaExt.Count > 0)
            {
                if (selectAreaExt.Count == 1)
                {
                    var selectMonitorAreaExts = m_ViewModel.MonitorAreaGateExts.Where(a => a.IsSelected).ToList();
                    if (selectMonitorAreaExts.Count <= 0)
                    {
                        isAreaGateSelected = false;
                        MessageBox.Show("请选择统计门面！");
                    }
                }
            }
            else
            {
                isAreaGateSelected = false;
                MessageBox.Show("请选择统计区域！");
            }
            if (isAreaGateSelected)
            {
                if (cmbInorOut.SelectedIndex >= 0)
                {
                    bool isIn = true;
                    isIn = cmbInorOut.SelectedIndex == 0 ? true : false;
                    m_ViewModel.MonitorSelectAreaGateExt(isIn);

                }
                else
                {
                    MessageBox.Show("请选择统计方式！");
                }
            }
        }

        private void btnExport_Click(object sender, RoutedEventArgs e)
        {
            SaveFileDialog fsd = new SaveFileDialog();
            //fsd.Filter = "PDF (*.pdf)|*.pdf";
            fsd.Filter = "PDF (*.pdf)|*.pdf|*PNG (*.png)|*.png";

            if (fsd.ShowDialog() == true)
            {

                //Create WriteableBitmap object which is what is being exported.
                WriteableBitmap wBitmap = new WriteableBitmap(spContent, null);
            
                
                int hgt = wBitmap.PixelHeight;
                int wdth = wBitmap.PixelWidth;

                //Create EditableImage oblect and iterrate through WriteableBitmap pixels to set EditableImage pixels
                EditableImage ei = new EditableImage(wdth, hgt);

                for (int y = 0; y < hgt; y++)
                {
                    for (int x = 0; x < wdth; x++)
                    {
                        int pixel = wBitmap.Pixels[((y * wdth) + x)];
                        ei.SetPixel(x, y, (byte)((pixel >> 16) & 0xff), (byte)((pixel >> 8) & 0xff), (byte)(pixel & 0xff), (byte)((pixel >> 24) & 0xff));
                    }
                }

                //Get the stream from the encoder and create byte array from it
                System.IO.Stream pngStream = ei.GetStream();

                printBuffer = new Byte[pngStream.Length];
                pngStream.Read(printBuffer, 0, printBuffer.Length);

                switch (fsd.FilterIndex)
                {
                    case 1:
                        HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create(new Uri(Application.Current.Host.Source.ToString().Substring(0, Application.Current.Host.Source.ToString().LastIndexOf("/")) + "/Png2Pdf.ashx"));
                        hwr.Method = "POST";

                        printStream = fsd.OpenFile();
                        printSyncContext = System.Threading.SynchronizationContext.Current;
                        hwr.BeginGetRequestStream(new AsyncCallback(PrintStart), hwr);

                        break;
                    case 2:
                        //Save the PNG to local disk
                        System.IO.Stream fs = fsd.OpenFile();
                        fs.Write(printBuffer, 0, printBuffer.Length);
                        fs.Close();
                        MessageBox.Show("You PNG has been created.", "Export Complete", MessageBoxButton.OK);
                        break;
                }

            }
        }

        #region Export PDF

        private Byte[] printBuffer;
        private System.Threading.SynchronizationContext printSyncContext;
        private System.IO.Stream printStream;

        private void PrintStart(IAsyncResult asynchronousResult)
        {
            HttpWebRequest hwr = (HttpWebRequest)asynchronousResult.AsyncState;
            System.IO.Stream stream = (System.IO.Stream)hwr.EndGetRequestStream(asynchronousResult);

            stream.Write(printBuffer, 0, printBuffer.Length);
            stream.Close();

            hwr.BeginGetResponse(new AsyncCallback(PrintGetResponse), hwr);
        }

        private void PrintGetResponse(IAsyncResult asynchronousResult)
        {
            HttpWebRequest hwr = (HttpWebRequest)asynchronousResult.AsyncState;
            WebResponse resp = hwr.EndGetResponse(asynchronousResult);
            System.IO.Stream respStream = resp.GetResponseStream();
            Byte[] respBytes = new Byte[respStream.Length];

            respStream.Read(respBytes, 0, respBytes.Length);

            printSyncContext.Post(PrintMergeThreads, new HttpWebRequestData(hwr, respBytes));
        }

        private void PrintMergeThreads(object state)
        {
            HttpWebRequestData hwrd = (HttpWebRequestData)state;

            printStream.Write(hwrd.Data, 0, hwrd.Data.Length);
            printStream.Close();
            printStream = null;
            printSyncContext = null;

            MessageBox.Show("Your PDF has been created.", "Export Complete", MessageBoxButton.OK);
        }

        #endregion

    }
}
